import os
import shutil
from datetime import datetime
from src.modules.media_processor import MediaProcessor
from src.utils.logger import log_info

from .utils import run_ffmpeg
from .video_normalizer import VideoNormalizer

class TransitionMerger:
    """处理视频合并和过渡效果"""
    
    def __init__(self, startupinfo=None, transition_effect=None, transition_duration=1.0, logger=None):
        self.startupinfo = startupinfo
        self.transition_effect = transition_effect
        self.transition_duration = transition_duration
        self.logger = logger
        self.media_processor = MediaProcessor(startupinfo, logger)
        self.video_normalizer = VideoNormalizer(startupinfo, logger)
    
    def _log_error(self, message):
        if self.logger:
            self.logger(message, level="error")
        else:
            from src.utils.logger import log_error
            log_error(message)
            
    def merge_videos_with_transitions(self, *video_paths, output_path=None, remove_voice=False, validate_func=None, separate_audio_func=None):
        """使用filter_complex一步完成多视频合并和过渡效果"""
        
        merge_method = "unknown"  # 追踪使用的合并方法
        transition_applied = False  # 追踪是否应用了过渡效果
        filter_complex = ""  # 存储filter_complex表达式
        
        try:
            # 验证输入和设置输出路径
            if validate_func:
                validate_func(*video_paths)
            base_dir = os.path.dirname(video_paths[0])
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            output_path = output_path or os.path.join(base_dir, f"merged_{timestamp}.mp4")
            
            # 单个视频直接处理
            if len(video_paths) == 1:
                log_info("[转场合并] 只有一个视频，直接复制")
                shutil.copy(video_paths[0], output_path)
                merge_method = "direct_copy"
                if remove_voice and separate_audio_func:
                    output_path = separate_audio_func(output_path)
                transition_applied = True
                return transition_applied
            
            # 开始记录处理过程
            log_info(f"[转场合并] 开始合并 {len(video_paths)} 个视频", highlight=True)
            log_info(f"[转场合并] 过渡效果: {self.transition_effect}, 持续时间: {self.transition_duration}秒")
            
            # 获取每个视频的详细信息
            video_durations = []
            has_audio = []
            resolutions = []
            log_info("[转场合并] 获取视频详细信息...")
            
            # 遍历所有视频获取信息
            for i, video_path in enumerate(video_paths):
                # 使用MediaLogger获取视频分辨率
                resolution = self.media_processor.get_video_resolution(video_path)
                if resolution:
                    resolutions.append(resolution)
                    log_info(f"[转场合并] 视频 #{i+1} 分辨率: {resolution[0]}x{resolution[1]}")
                else:
                    raise ValueError(f"无法获取视频 #{i+1} 分辨率")
                
                # 获取视频时长
                duration = self.media_processor.get_media_duration(video_path)
                if duration is not None:
                    video_durations.append(duration)
                    log_info(f"[转场合并] 视频 #{i+1} 时长: {duration}秒")
                    
                    # 检查过渡效果是否适合视频长度
                    if self.transition_effect and duration < self.transition_duration * 1.5:
                        log_info(f"[转场合并] 警告: 视频 #{i+1} 时长({duration}秒)不足以支持 {self.transition_duration}秒 的过渡")
                else:
                    raise ValueError(f"无法获取视频 #{i+1} 时长")
                
                # 检查音频流
                has_audio_stream = self.media_processor.has_audio_stream(video_path)
                has_audio.append(has_audio_stream)
                log_info(f"[转场合并] 视频 #{i+1} 音频: {'有' if has_audio_stream else '无'}")
                
            # 计算最大分辨率作为目标分辨率
            if resolutions:
                target_width = max(res[0] for res in resolutions)
                target_height = max(res[1] for res in resolutions)
                log_info(f"[转场合并] 目标分辨率设置为: {target_width}x{target_height} (最大宽高)")
            else:
                raise ValueError("没有有效的视频分辨率信息")

            # 标准化所有视频为相同格式
            log_info("[转场合并] 标准化视频格式...")
            normalized_videos = []
            for i, video_path in enumerate(video_paths):
                log_info(f"[转场合并] 标准化视频 #{i+1}: {os.path.basename(video_path)}")
                norm_path = self.video_normalizer.normalize_video(
                    video_path, 
                    target_width=target_width, 
                    target_height=target_height
                )
                normalized_videos.append(norm_path)
                
            # 使用filter_complex构建命令 
            # 使用filter_complex构建命令
            cmd = ["ffmpeg"]

            # 添加所有输入
            for video_path in normalized_videos:
                cmd.extend(["-i", video_path])

            # 为每个视频添加标准化处理 - 详细记录filter构建过程
            log_info("[转场合并] 构建filter_complex表达式...")

            # 为每个视频添加标准化处理 - 保留原始宽高比
            for i in range(len(normalized_videos)):
                # 视频处理 - 保持原始比例并居中填充
                filter_part = f"[{i}:v]fps=30,scale={target_width}:{target_height}:force_original_aspect_ratio=decrease,pad={target_width}:{target_height}:(ow-iw)/2:(oh-ih)/2,setsar=1:1,format=yuv420p[v{i}];"
                filter_complex += filter_part
                log_info(f"[转场合并] 视频 #{i+1} 滤镜: {filter_part}")
                
                # 音频处理部分保持不变
                if has_audio[i]:
                    audio_part = f"[{i}:a]aformat=sample_rates=44100:channel_layouts=stereo[a{i}];"
                    filter_complex += audio_part
                    log_info(f"[转场合并] 音频 #{i+1} 滤镜: {audio_part}")
                else:
                    # 为没有音频的视频生成静音轨道
                    audio_part = f"anullsrc=r=44100:cl=stereo:d={video_durations[i]}[a{i}];"
                    filter_complex += audio_part
                    log_info(f"[转场合并] 视频 #{i+1} 无音频，添加静音轨道: {audio_part}")

            # 使用过渡效果进行合并
            if self.transition_effect and len(normalized_videos) >= 2:
                log_info("[转场合并] 添加过渡效果滤镜...")
                
                # 处理第一对视频 - 精确计算offset
                # 关键修复: 确保offset正好是第一个视频长度减去过渡时间
                first_offset = video_durations[0] - self.transition_duration
                first_transition = f"[v0][v1]xfade=transition={self.transition_effect}:duration={self.transition_duration}:offset={first_offset}[vtmp1];"
                filter_complex += first_transition
                log_info(f"[转场合并] 第1个过渡: {first_transition} (offset={first_offset:.2f}秒)")
                
                # 修复: 更准确计算累计时长
                # 第一个视频的有效时长 + 第二个视频的时长 - 过渡时间
                cumulative_duration = video_durations[0] + video_durations[1] - self.transition_duration
                
                # 处理剩余视频
                for i in range(2, len(normalized_videos)):
                    # 关键修复: 精确计算每个过渡的offset
                    next_offset = cumulative_duration - self.transition_duration
                    next_transition = f"[vtmp{i-1}][v{i}]xfade=transition={self.transition_effect}:duration={self.transition_duration}:offset={next_offset}[vtmp{i}];"
                    filter_complex += next_transition
                    log_info(f"[转场合并] 第{i}个过渡: {next_transition} (offset={next_offset:.2f}秒)")
                    
                    # 修复: 更精确地更新累计时长，不再使用max函数
                    cumulative_duration += video_durations[i] - self.transition_duration
                
                # 添加额外修复: 为最终视频添加精确时长控制
                # 计算最终视频的精确长度
                final_duration = sum(video_durations) - (len(normalized_videos) - 1) * self.transition_duration
                
                # 添加精确时长控制，防止末尾静止帧
                # 修改最终输出标签
                final_video_tmp = f"vtmp{len(normalized_videos)-1}"
                filter_complex += f"[{final_video_tmp}]trim=0:{final_duration}[vout];"
                final_video = "[vout]"
                
                # 处理音频 - 合并所有音频流并同样精确控制时长
                audio_streams = "".join([f"[a{i}]" for i in range(len(normalized_videos))])
                audio_concat = f"{audio_streams}concat=n={len(normalized_videos)}:v=0:a=1:unsafe=1[atmp];"
                filter_complex += audio_concat + f"[atmp]atrim=0:{final_duration}[aout];"
                
                final_audio = "[aout]"  # 使用合并且修剪后的音频
                transition_applied = True
                merge_method = "filter_complex_with_transition"
                log_info(f"[转场合并] 最终视频输出: {final_video}, 音频输出: {final_audio}, 精确控制时长: {final_duration:.2f}秒")
            else:
                log_info("[转场合并] 使用简单concat滤镜...")
                # 使用简单concat
                v_streams = "".join([f"[v{i}]" for i in range(len(normalized_videos))])
                a_streams = "".join([f"[a{i}]" for i in range(len(normalized_videos))])
                
                video_concat = f"{v_streams}concat=n={len(normalized_videos)}:v=1:a=0:unsafe=1[vout];"
                audio_concat = f"{a_streams}concat=n={len(normalized_videos)}:v=0:a=1:unsafe=1[aout];"
                
                filter_complex += video_concat + audio_concat
                log_info(f"[转场合并] 视频串联: {video_concat}")
                log_info(f"[转场合并] 音频串联: {audio_concat}")
                transition_applied = True
                final_video = "[vout]"
                final_audio = "[aout]"
                merge_method = "filter_complex_concat"

            # 完整记录filter_complex表达式
            log_info(f"[转场合并] 完整filter_complex表达式: {filter_complex}")

            # 确保命令结构正确
            cmd.extend([
                "-filter_complex", filter_complex,
                "-map", final_video, 
                "-map", final_audio,
                "-c:v", "libx264",
                "-pix_fmt", "yuv420p",  # 显式指定像素格式
                "-profile:v", "main",   # 更兼容的配置文件
                "-level", "4.0",
                "-preset", "medium", 
                "-crf", "23",
                "-c:a", "aac",
                "-b:a", "192k",
                "-ar", "44100",
                "-movflags", "+faststart",  # 优化流媒体播放
                "-max_muxing_queue_size", "1024",  # 处理复杂拼接时避免队列溢出
                "-y",
                output_path
            ])

            # 执行命令并详细记录
            log_info(f"[转场合并] 开始执行ffmpeg合并命令...", highlight=True)
            result = run_ffmpeg(cmd, "视频过渡合并", self.startupinfo, self.logger)
            
            log_info(f"[转场合并] 合并成功完成: {output_path}", highlight=True)
            
            # 如果需要移除人声
            if remove_voice and separate_audio_func:
                log_info("[转场合并] 开始移除人声...")
                output_path = separate_audio_func(output_path)
                
            return transition_applied
            
        except Exception as e:
            # 捕获并记录详细错误信息
            import traceback
            error_details = traceback.format_exc()
            transition_applied = False
            log_info(f"[转场合并] 视频合并失败，错误类型: {type(e).__name__}")
            log_info(f"[转场合并] 错误信息: {str(e)}")
            log_info(f"[转场合并] 详细错误栈:\n{error_details}")
            
            # 分析可能的错误原因
            # ... 省略详细实现 ...
            
            # 重新抛出异常，但附带更有用的错误信息
            raise RuntimeError(f"视频合并失败: {str(e)}") from e